package com.ldfile.server.utils;

import com.ldfile.server.config.FileServiceInfoConfiguration;
import com.ldfile.server.entity.FileResponseEntity;
import com.ldfile.server.exception.FileServerException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * @author callmecool.ldsoft
 * @description tools
 * @since 2020/7/30 13:47
 */
@Component
@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class FileUploadUtils {
    private final FileServiceInfoConfiguration fileServiceInfoConfiguration;
    private final static String PREFIX_VIDEO = "video/";

    /**
     * 保存文件
     */
    public List<FileResponseEntity> save(HttpServletRequest request) {
        MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
        List<MultipartFile> files = multipartHttpServletRequest.getFiles("file");
        return files.stream().map(file -> this.saveFile(file)).collect(Collectors.toList());
    }

    /**
     * 保存文件实现
     */
    private FileResponseEntity saveFile(MultipartFile file) {
        try {
            if (file == null) {
                throw new FileServerException("上传文件为空");
            }
            String originalFilename = file.getOriginalFilename();
            if (StringUtils.isEmpty(file.getContentType()) || StringUtils.isEmpty(originalFilename)) {
                throw new FileServerException("无法识别" + originalFilename + "文件！");
            }
            String thisMonthStr = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM"));
            File pho = new File(fileServiceInfoConfiguration.getDirYml(), thisMonthStr);
            if (!pho.exists()) {
                if (!pho.mkdirs()) {
                    throw new FileServerException("文件上传失败");
                }
            }
            log.debug("文件：{}的mime类型为{}", file.getResource().getFilename(), file.getContentType());
//            if (!ValidateMime.validateFileMime(file.getContentType())) {
//                throw new FileServerException(file.getResource().getFilename() + ",不支持该类文件！");
//            }


            // 让文件保留原有后缀
            String suffix = originalFilename.indexOf(".") < 0 ? "" : originalFilename.substring(originalFilename.lastIndexOf("."));
            // 将二进制流写入硬盘
            InputStream inputStream = file.getInputStream();
            byte[] data = new byte[1024];
            int length;
            String fileName = UUID.randomUUID() + suffix;
            File targetFile = new File(pho, fileName);
            OutputStream outputStream = new FileOutputStream(targetFile);
            while ((length = inputStream.read(data)) != -1) {
                // 将byte写入硬盘
                outputStream.write(data, 0, length);
            }
            // 关闭流，不关闭会导致文件已打开无法删除
            outputStream.close();
            log.debug("文件：{}上传成功！", file.getResource().getFilename());
            log.debug("文件保存位置：{}", pho.getAbsolutePath());
            log.debug("文件访问路径：{}", fileServiceInfoConfiguration.getUrlYml() + fileServiceInfoConfiguration.getPathYml() + "/" + thisMonthStr + "/" + fileName);
//            String videofile = fileServiceInfoConfiguration.getUrlYml() + fileServiceInfoConfiguration.getPathYml() + "/" + fileName;
//            int idx = videofile.lastIndexOf(".");
//            String framefile= UUID.randomUUID() + ".jpeg";

//            if (file.getContentType().contains(PREFIX_VIDEO)){
////             FetchFrame.fetchFrames(videofile,framefile);
//                Frame frame = VideoFrameKit.fetchFrame(videofile);
//                Java2DFrameConverter converter =new Java2DFrameConverter();
//                BufferedImage bi =converter.getBufferedImage(frame);
//
//                ByteArrayOutputStream stream = new ByteArrayOutputStream();
//
//                boolean write = ImageIO.write(bi, "jpeg", stream);
//                byte[] bytes = stream.toByteArray();
//                OutputStream output = new FileOutputStream(new File(fileServiceInfoConfiguration.getDirYml() + File.separator + framefile));
//                output.write(bytes);
//                return FileResponseEntity.builder().success(true).result(fileServiceInfoConfiguration.getUrlYml() + fileServiceInfoConfiguration.getPathYml() + "/" + fileName)
//                        .content(fileServiceInfoConfiguration.getUrlYml() + fileServiceInfoConfiguration.getPathYml() + "/" +framefile).build();
//            }
            return FileResponseEntity.builder().success(true).result(fileServiceInfoConfiguration.getUrlYml() + fileServiceInfoConfiguration.getPathYml() + "/" + thisMonthStr + "/" + fileName).build();
        } catch (Exception e) {
            if (file != null) {
                log.error("文件{}上传失败！错误原因：{}", file.getResource().getFilename(), e.getMessage());
            } else {
                log.error("上传失败，文件为空！");
            }
            return FileResponseEntity.builder().success(false).result(e.getMessage()).build();
        }
    }

    /**
     * 删除文件
     */
    public List<FileResponseEntity> del(List<String> urls) {
        return urls.stream().map(this::delFile).collect(Collectors.toList());
    }

    /**
     * 删除文件实现
     */
    private FileResponseEntity delFile(String url) {
        try {
            String fileName = url.replaceFirst(fileServiceInfoConfiguration.getUrlYml() + fileServiceInfoConfiguration.getPathYml() + "/", fileServiceInfoConfiguration.getDirYml());
            File file = new File(fileName);
            if (!file.exists()) {
                throw new FileServerException("文件不存在！");
            }
            if (!file.delete()) {
                throw new FileServerException("文件" + fileName + "删除失败！");
            }
            log.info("文件删除成功！文件地址：{}", url);
            return FileResponseEntity.builder().success(true).result("文件删除成功！").build();
        } catch (Exception e) {
            log.info("文件删除失败！文件地址：{}, 错误信息：{}", url, e.getMessage());
            return FileResponseEntity.builder().success(false).result(e.getMessage()).build();
        }
    }
}
